import * as Matter from 'matter-js';
import { FruitType, GameFruit, Position } from '../types/game';
import { GAME_CONFIG } from '../config/fruits';

export class GameEngine {
  public engine: Matter.Engine;
  public world: Matter.World;
  public render: Matter.Render | null = null;
  private canvas: HTMLCanvasElement | null = null;
  private container: HTMLElement | null = null;
  private ctx: CanvasRenderingContext2D | null = null;
  
  // 游戏边界
  public walls: Matter.Body[] = [];
  
  // 事件回调
  public onFruitCollision?: (fruit1: GameFruit, fruit2: GameFruit) => void;
  public onGameOver?: () => void;

  constructor() {
    // 创建物理引擎
    this.engine = Matter.Engine.create();
    this.world = this.engine.world;
    
    // 设置重力
    this.engine.world.gravity.y = GAME_CONFIG.GRAVITY;
    
    // 禁用睡眠状态以保持动画流畅
    this.engine.enableSleeping = false;
  }

  // 初始化渲染器
  public initRender(container: HTMLElement): void {
    try {
      console.log('开始初始化渲染器...');
      this.container = container;
      
      // 创建canvas
      this.canvas = document.createElement('canvas');
      this.canvas.width = GAME_CONFIG.CONTAINER_WIDTH;
      this.canvas.height = GAME_CONFIG.CONTAINER_HEIGHT;
      this.canvas.style.border = '3px solid #ff6b6b';
      this.canvas.style.borderRadius = '20px';
      this.canvas.style.backgroundColor = '#fff5f5';
      this.canvas.style.boxShadow = '0 10px 30px rgba(255, 107, 107, 0.3)';
      
      container.appendChild(this.canvas);
      console.log('Canvas创建成功');
      
      // 获取2D渲染上下文
      this.ctx = this.canvas.getContext('2d');
      if (!this.ctx) {
        throw new Error('无法获取Canvas 2D上下文');
      }
      
      // 创建Matter.js渲染器
      this.render = Matter.Render.create({
        canvas: this.canvas,
        engine: this.engine,
        options: {
          width: GAME_CONFIG.CONTAINER_WIDTH,
          height: GAME_CONFIG.CONTAINER_HEIGHT,
          wireframes: false,
          background: 'transparent',
          showVelocity: false,
          showAngleIndicator: false,
          showDebug: false
        }
      });
      console.log('Matter.js渲染器创建成功');

      // 创建游戏边界墙壁
      this.createWalls();
      console.log('游戏边界创建成功');
      
      // 设置碰撞检测
      this.setupCollisionDetection();
      console.log('碰撞检测设置成功');
      
      // 启动渲染器
      Matter.Render.run(this.render);
      console.log('渲染器启动成功');
      
      // 设置自定义渲染
      this.setupCustomRender();
      
      // 启动物理引擎
      const runner = Matter.Runner.create();
      Matter.Runner.run(runner, this.engine);
      console.log('物理引擎启动成功');
      
    } catch (error) {
      console.error('渲染器初始化失败:', error);
      throw error;
    }
  }

  // 创建游戏边界
  private createWalls(): void {
    const { CONTAINER_WIDTH, CONTAINER_HEIGHT, WALL_THICKNESS } = GAME_CONFIG;
    
    // 底部墙壁
    const ground = Matter.Bodies.rectangle(
      CONTAINER_WIDTH / 2,
      CONTAINER_HEIGHT - WALL_THICKNESS / 2,
      CONTAINER_WIDTH,
      WALL_THICKNESS,
      { 
        isStatic: true,
        render: { fillStyle: '#ff6b6b' }
      }
    );
    
    // 左墙壁
    const leftWall = Matter.Bodies.rectangle(
      WALL_THICKNESS / 2,
      CONTAINER_HEIGHT / 2,
      WALL_THICKNESS,
      CONTAINER_HEIGHT,
      { 
        isStatic: true,
        render: { fillStyle: '#ff6b6b' }
      }
    );
    
    // 右墙壁
    const rightWall = Matter.Bodies.rectangle(
      CONTAINER_WIDTH - WALL_THICKNESS / 2,
      CONTAINER_HEIGHT / 2,
      WALL_THICKNESS,
      CONTAINER_HEIGHT,
      { 
        isStatic: true,
        render: { fillStyle: '#ff6b6b' }
      }
    );

    this.walls = [ground, leftWall, rightWall];
    Matter.World.add(this.world, this.walls);
  }

  // 设置碰撞检测
  private setupCollisionDetection(): void {
    Matter.Events.on(this.engine, 'collisionStart', (event) => {
      const pairs = event.pairs;
      
      pairs.forEach((pair) => {
        const { bodyA, bodyB } = pair;
        
        // 检查是否是水果之间的碰撞
        if (bodyA.label === 'fruit' && bodyB.label === 'fruit') {
          const fruitA = bodyA.plugin?.fruit as GameFruit;
          const fruitB = bodyB.plugin?.fruit as GameFruit;
          
          if (fruitA && fruitB && this.onFruitCollision) {
            this.onFruitCollision(fruitA, fruitB);
          }
        }
      });
    });

    // 检查游戏结束条件
    Matter.Events.on(this.engine, 'afterUpdate', () => {
      this.checkGameOver();
    });
  }

  // 创建水果物理体
  public createFruit(fruitType: FruitType, position: Position): GameFruit {
    const body = Matter.Bodies.circle(
      position.x,
      position.y,
      fruitType.radius,
      {
        mass: fruitType.mass,
        restitution: GAME_CONFIG.RESTITUTION,
        friction: GAME_CONFIG.FRICTION,
        label: 'fruit',
        render: {
          fillStyle: 'transparent',
          strokeStyle: '#fff',
          lineWidth: 2
        }
      }
    );

    const fruit: GameFruit = {
      id: `fruit_${Date.now()}_${Math.random()}`,
      type: fruitType,
      body
    };

    // 将水果信息附加到物理体
    body.plugin = { fruit };
    
    // 添加到物理世界
    Matter.World.add(this.world, body);
    
    return fruit;
  }

  // 移除水果
  public removeFruit(fruit: GameFruit): void {
    Matter.World.remove(this.world, fruit.body);
  }

  // 检查游戏结束
  private checkGameOver(): void {
    const bodies = Matter.Composite.allBodies(this.world);
    
    for (const body of bodies) {
      if (body.label === 'fruit' && body.position.y < GAME_CONFIG.GAME_OVER_LINE_Y) {
        // 检查水果是否已经静止（避免误判）
        if (Math.abs(body.velocity.y) < 0.1 && Math.abs(body.velocity.x) < 0.1) {
          if (this.onGameOver) {
            this.onGameOver();
          }
          break;
        }
      }
    }
  }

  // 清理所有水果
  public clearFruits(): void {
    const bodies = Matter.Composite.allBodies(this.world);
    const fruitBodies = bodies.filter(body => body.label === 'fruit');
    
    fruitBodies.forEach(body => {
      Matter.World.remove(this.world, body);
    });
  }

  // 获取鼠标/触摸位置在游戏世界中的坐标
  public getWorldPosition(clientX: number, clientY: number): Position | null {
    if (!this.canvas) return null;
    
    const rect = this.canvas.getBoundingClientRect();
    const x = clientX - rect.left;
    const y = clientY - rect.top;
    
    // 限制在游戏区域内
    const constrainedX = Math.max(
      GAME_CONFIG.WALL_THICKNESS + 20,
      Math.min(x, GAME_CONFIG.CONTAINER_WIDTH - GAME_CONFIG.WALL_THICKNESS - 20)
    );
    
    return { x: constrainedX, y };
  }

  // 设置自定义渲染
  private setupCustomRender(): void {
    if (!this.ctx) return;
    
    // 添加渲染事件监听器，在Matter.js渲染之后绘制emoji
    Matter.Events.on(this.render as Matter.Render, 'afterRender', () => {
      this.renderFruitEmojis();
    });
  }

  // 渲染水果emoji
  private renderFruitEmojis(): void {
    if (!this.ctx) return;
    
    const bodies = Matter.Composite.allBodies(this.world);
    
    bodies.forEach(body => {
      if (body.label === 'fruit' && body.plugin?.fruit) {
        const fruit = body.plugin.fruit as GameFruit;
        const { x, y } = body.position;
        const radius = fruit.type.radius;
        
        // 设置文本样式
        this.ctx.textAlign = 'center';
        this.ctx.textBaseline = 'middle';
        this.ctx.font = `${radius * 1.4}px Arial`;
        
        // 绘制背景圆圈
        this.ctx.fillStyle = fruit.type.color;
        this.ctx.beginPath();
        this.ctx.arc(x, y, radius, 0, 2 * Math.PI);
        this.ctx.fill();
        
        // 绘制白色边框
        this.ctx.strokeStyle = '#fff';
        this.ctx.lineWidth = 2;
        this.ctx.stroke();
        
        // 绘制emoji
        this.ctx.fillStyle = '#fff';
        this.ctx.fillText(fruit.type.emoji, x, y);
      }
    });
  }

  // 销毁引擎
  public destroy(): void {
    if (this.render) {
      Matter.Render.stop(this.render);
      this.render.canvas.remove();
      this.render.canvas = null as any;
      this.render.context = null as any;
      this.render.textures = {};
    }
    
    Matter.Engine.clear(this.engine);
    
    if (this.canvas && this.container) {
      this.container.removeChild(this.canvas);
    }
  }
}